 package com.cattsoft.util.common.dao.hibernateimpl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.cattsoft.util.common.dao.IGenericDao;
import com.cattsoft.util.common.exception.OssSystemException;



public class GenericDaoHibernateImpl<T, PK extends Serializable> extends
		HibernateDaoSupport implements IGenericDao<T, PK> {

	@SuppressWarnings("unchecked")
	public T findByPK(Class<T> type, PK id) {
		T t = null;
		try {
			t = (T) getHibernateTemplate().get(type, id);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by PK fail");
		}
		return t;
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll(Class<T> type) {
		List<T> list = null;
		try {
			list = getHibernateTemplate().loadAll(type);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find all fail");
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<T> findByHql(String hql, Object[] queryArgs) {
		List<T> list = null;
		try {
			list = getHibernateTemplate().find(hql, queryArgs);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by hql fail");
		}
		return list;
	}
	@SuppressWarnings("unchecked")
	public List<T> findByHql(String hql, Object queryArg) {
		List<T> list = null;
		try {
			list = getHibernateTemplate().find(hql, queryArg);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by hql fail");
		}
		return list;
	}
	@SuppressWarnings("unchecked")
	public List<T> findByHql(String hql) {
		List<T> list = null;
		try {
			list = getHibernateTemplate().find(hql);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by hql fail");
		}
		return list;
	}
	public boolean save(T newInstance) {
		boolean state = false;
		try {
			this.getHibernateTemplate().saveOrUpdate(newInstance);
			state = true;
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "save fail");
		}
		return state;
	}

	public boolean delete(T persistentObject) {
		boolean state = false;
		try {
			
			getHibernateTemplate().delete(persistentObject);
			state=true;
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "delete fail");
		}
		return state;
	}
	
	public boolean deleteByPKs(Class<T> type, PK[] PKs) {
		boolean state = false;
		for (int i = 0; i < PKs.length; i++) {
			state= delete(findByPK(type, PKs[i]));
			 
		}
		return state;
	}
	public boolean deleteByPK(Class<T> type, PK pk) {
		return delete(findByPK(type,pk));
	}
	
	
	public boolean deleteAll(Collection objs) {
		boolean flag = false;
		try{
			this.getHibernateTemplate().deleteAll(objs);
			flag = true;
		}catch(Exception e){
			e.printStackTrace();
			throw new OssSystemException("", "delete fail");
		}
		return flag;
	}
	
	public boolean deleteAll(List list) {
		boolean flag = false;
		try{
			this.getHibernateTemplate().deleteAll(list);
			flag = true;
		}catch(Exception e){
			e.printStackTrace();
			throw new OssSystemException("", "delete fail");
		}
		return flag;
	}

	public void updataAll(String hql, Object updataArg) throws OssSystemException {
		try {
			getHibernateTemplate().update(hql, updataArg);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by hql fail");
		}
	}
	public void updataAll(Object hql) throws OssSystemException {
		try {
			getHibernateTemplate().update(hql);
		} catch (Exception e) {
			e.printStackTrace();
			throw new OssSystemException("", "find by hql fail");
		}
	}

 
	public List findByPage(final String hql,final Object[] o,final int start,final int size)
			throws OssSystemException {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().executeFind(new HibernateCallback(){

			 
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				// TODO Auto-generated method stub
				Query query= session.createQuery(hql);
				if(o!=null){
					for(int i=0;i<o.length;i++){
						query.setParameter(i, o[i]);
					}
					query.setFirstResult(start).setMaxResults(size);
					return query.list();
				}
				return null;
			}
			
		});
	}

	 
	public void saveOrUpdate(Object o) throws OssSystemException {
		// TODO Auto-generated method stub
		getHibernateTemplate().saveOrUpdate(o);
	}

	 
	public void updateOrDelete(final String hql,final Object[] o)
			throws OssSystemException {
		// TODO Auto-generated method stub
		getHibernateTemplate().execute(new HibernateCallback(){			 
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				// TODO Auto-generated method stub
				Query query= session.createQuery(hql);
				if(o!=null){
					for(int i=0;i<o.length;i++){
						query.setParameter(i, o[i]);
					}
					query.executeUpdate();
				}
				return null;
			}
			
		});
	}
}
